using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.IO;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;

[assembly : WebResource("CodeStory.WebControls.Resource.ValidateImage.js", "application/x-javascript")]

namespace CodeStory.WebControls
{
	[ToolboxData("<{0}:ValidateImage runat=server></{0}:ValidateImage>")]
	public class ValidateImage : WebControl, INamingContainer, IPostBackDataHandler, IValidator
	{
		private const string KEY = "CodeStory.WebControls.ValidateImage.Initialize";
		private bool _isvalid = false;
		private string _UserInput = string.Empty;
		private string imageSeed = string.Empty;
		private ITemplate layoutTemplate;
		private ValidateImageContainer templateContainer;

		[DefaultValue(6)]
		public int CodeLength {
			get {
				object obj = ViewState["CodeLength"];
				return obj == null ? 6 : (int)obj;
			}
			set {
				int r = 6;
				if (value > 3 || value < 13) {
					r = value;
				}
				ViewState["CodeLength"] = r;
			}
		}

		[TemplateContainer(typeof(ValidateImage))]
		[PersistenceMode(PersistenceMode.InnerProperty)]
		[Browsable(false)]
		public ITemplate LayoutTemplate {
			get { return layoutTemplate; }
			set {
				layoutTemplate = value;
				ChildControlsCreated = false;
			}
		}

		[Browsable(false)]
		private string HtmlInputClientID {
			get {
				object obj = ViewState["HtmlInputClientID"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { ViewState["HtmlInputClientID"] = value; }
		}
		[Browsable(false)]
		private string HtmlInputUniqueID {
			get {
				object obj = ViewState["HtmlInputUniqueID"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { ViewState["HtmlInputUniqueID"] = value; }
		}
		[Browsable(false)]
		private string UserInputUniqueID {
			get {
				object obj = ViewState["UserInputUniqueID"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { ViewState["UserInputUniqueID"] = value; }
		}
		private string ImageSeed {
			get { return imageSeed; }
			set { imageSeed = value; }
		}
		internal bool InternalDesignMode {
			get { return this.DesignMode; }
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		private ValidateImageContainer TemplateContainer {
			get {
				this.EnsureChildControls();
				return this.templateContainer;
			}
		}

		#region IPostBackDataHandler Members
		bool IPostBackDataHandler.LoadPostData(string postDataKey, NameValueCollection postCollection) {
			return LoadPostData(postDataKey, postCollection);
		}

		void IPostBackDataHandler.RaisePostDataChangedEvent() {
			RaisePostDataChangedEvent();
		}
		#endregion

		#region IValidator Members
		public string ErrorMessage {
			get {
				object obj = ViewState["ErrorMessage"];
				return obj == null ? string.Empty : (string)obj;
			}
			set { ViewState["ErrorMessage"] = value; }
		}
		public bool IsValid {
			get { return _isvalid; }
			set { _isvalid = value; }
		}

		public void Validate() {
			string str = CodeGenerator.Generate(ImageSeed, CodeLength);
			IsValid = string.Equals(str, _UserInput, StringComparison.OrdinalIgnoreCase);
		}
		#endregion

		protected override void OnInit(EventArgs e) {
			object obj = Context.Application[KEY];
			bool initialized = obj == null ? false : (bool)obj;
			if (!initialized) {
				Context.Application[KEY] = true;
				string filename = Path.Combine(Context.Request.PhysicalApplicationPath, "CodeStory_client/ValidateImage/web.config");
				CodeStoryUtility.RegisterFile(filename, "CodeStory.WebControls.Resource.ValidateImageWeb.config");
			}
			base.OnInit(e);
		}

		protected override void CreateChildControls() {
			ChildControlsCreated = true;
			templateContainer = new ValidateImageContainer(this);
			if (layoutTemplate == null) {
				templateContainer.EnableViewState = false;
				templateContainer.EnableTheming = false;
				layoutTemplate = new ValidateImageTemplate(this);
			}
			Controls.Add(templateContainer);
			templateContainer.Visible = true;
			layoutTemplate.InstantiateIn(templateContainer);

			HtmlInputHidden hidden = new HtmlInputHidden();
			templateContainer.Controls.Add(hidden);
			hidden.ID = "Hidden";
			HtmlInputClientID = hidden.ClientID;
			HtmlInputUniqueID = hidden.UniqueID;
			UserInputUniqueID = templateContainer.UserInputTextBox.UniqueID;
		}

		protected override void AddAttributesToRender(HtmlTextWriter writer) {
			HtmlInputHidden hidden = TemplateContainer.HiddenControl as HtmlInputHidden;
			if (hidden != null) {
				hidden.Value = ImageSeed;
			}
			Image image = TemplateContainer.Image as Image;
			if (image != null) {
				image.ImageUrl = string.Format("~/CodeStory_client/ValidateImage/GetImage.aspx?seed={0}&length{1}", ImageSeed, CodeLength);
				image.Attributes.Add("onclick", string.Format("javascript:ValidateImage.Reset(this,'{0}',{1});", this.HtmlInputClientID, CodeLength));
			}
			base.AddAttributesToRender(writer);
		}

		protected override void OnPreRender(EventArgs e) {
			if (Page != null) {
				Page.RegisterRequiresPostBack(this);
				Page.ClientScript.RegisterClientScriptResource(typeof(DataSourceHelper), "CodeStory.WebControls.Resource.CodeStory.js");
				Page.ClientScript.RegisterClientScriptResource(GetType(), "CodeStory.WebControls.Resource.ValidateImage.js");
			}
			base.OnPreRender(e);
		}

		public bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
			string seed = postCollection[HtmlInputUniqueID];
			string userinput = postCollection[UserInputUniqueID];
			if (!string.IsNullOrEmpty(seed)) {
				ImageSeed = seed;
				_UserInput = userinput;
				return true;
			}
			return false;
		}

		public void RaisePostDataChangedEvent() {
			Validate();
		}
	}
}